package com.tfswx.jkgl.core.task;

import com.tfswx.jkgl.core.utils.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author ricky
 * @date 2021/12/27
 */
@Slf4j
public class ServiceTaskContextHolder {
    private static final ThreadLocal<Map<String, List<ServiceTask>>> contextHolder = new ThreadLocal<>();

    public static void addTask(ServiceTask task, String id) {
        Map<String, List<ServiceTask>> stringListMap = contextHolder.get();
        if (stringListMap == null) {
            stringListMap = new HashMap<>();
            contextHolder.set(stringListMap);
        }
        List<ServiceTask> serviceTasks = stringListMap.computeIfAbsent(id, k -> new ArrayList<>());
        serviceTasks.add(task);
    }

    public static void clearDataSourceType() {
        contextHolder.remove();
    }

    public static void startTask(Object dto, String id) {
        Map<String, List<ServiceTask>> stringListMap = contextHolder.get();
        if (stringListMap == null) {
            return;
        }
        try {
            List<ServiceTask> serviceTasks = stringListMap.computeIfAbsent(id, k -> new ArrayList<>());
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
            CountDownLatch count = new CountDownLatch(serviceTasks.size());
            List<String> errList = new ArrayList<>();
            for (ServiceTask serviceTask : serviceTasks) {
                threadPoolExecutor.execute(() -> {
                    try {
                        serviceTask.run(dto);
                    } catch (Exception e) {
                        errList.add(ExceptionUtil.getMessage(e));
                    } finally {
                        count.countDown();
                    }
                });
            }
            try {
                count.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            StringBuilder err = new StringBuilder();
            for (int i = 0; i < errList.size(); i++) {
                String s = errList.get(i);
                err.append(i + 1).append("、").append(s).append(";");
            }
            if (err.length() > 0) {
                throw new RuntimeException(err.toString());
            }
        } finally {
            stringListMap.remove(id);
            // clearDataSourceType();
        }
    }
}
